import type { RouterContext } from "https://deno.land/x/oak@v17.1.1/mod.ts";

import { AppState } from "../router/index.ts";
import client from "../db/index.ts";

type CallbackType = (utils: {
  getQuery: () => URLSearchParams;
  getBody: () => object;
  getUser: () => Promise<object | null>;
}) => Promise<object> | object;

const withRequest = (callback: CallbackType, auth = false) => {
  return async (ctx: RouterContext<"/", Record<string | number, string | undefined>, AppState>) => {
    const user_id = ctx.state.session.get("user_id");
    ctx.response.headers.set("Content-Type", "application/json");
    if (!user_id && auth) {
      ctx.response.body = JSON.stringify({ code: 401, resMsg: "Unauthorized", data: null });
      return;
    }
    const getQuery = () => new URLSearchParams(ctx.request.url.search);
    const getBody = () => ctx.request.body;
    const getUser = async () => {
      if (!user_id) return null;
      const result = await client.queryObject(`SELECT * FROM sys_user WHERE id = ?`, [user_id])
      return result.rows[0] as object;
    }
    let data = null;
    try {
      data = await callback({ getQuery, getBody, getUser })
    } catch (e) {
      console.log(e)
      ctx.response.body = JSON.stringify({ code: 500, resMsg: "Internal Server Error", data: null });
      return;
    }
    ctx.response.body = JSON.stringify({ code: 200, resMsg: "success", data });
  }
}
export default withRequest